/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ch.poole.openinghoursfragment.menu;


import ch.poole.openinghoursfragment.OnMenuItemClickListener;
import ch.poole.openinghoursfragment.ResourceTable;
import ch.poole.openinghoursfragment.WindowUtil;

import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.components.element.ShapeElement;

import ohos.agp.utils.Color;
import ohos.agp.utils.Rect;
import ohos.agp.utils.TextAlignment;
import ohos.agp.window.dialog.PopupDialog;

import ohos.app.Context;

import ohos.global.resource.NotExistException;
import ohos.global.resource.Resource;
import ohos.global.resource.WrongTypeException;

import java.io.IOException;

import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * MenuPop
 */
public class MenuPop extends PopupDialog {
    private Context context;
    private DirectionalLayout content;
    /**
     * 弹窗显示的位置不能超越Window高度
     */
    float maxY;
    int overflow;
    float centerY = 0;
    /**
     * 是否显示在上方
     */
    public boolean isShowUp;
    /**
     * 是否显示在左边
     */
    public boolean isShowLeft;

    private DirectionalLayout itemWorb;
    private ArrayList<MenuItem> menuItems;
    /**
     * 用与改变pop的宽度
     * 0 表示 worbContent  1 表示matchParent
     * 默认 worbContent
     */
    private int popWidthType = 0;
    private boolean showBootom;
    /**
     * 执行倚靠逻辑
     */
    public float translationX = 0;
    /**
     * 执行倚靠逻辑
     */
    public float translationY = 0;

    /**
     * 构造方法
     *
     * @param context context
     */
    public MenuPop(Context context) {
        super(context, null);
        this.context = context;
        maxY = MenuUtils.getScreenHeight(context);
        overflow = MenuUtils.vp2px(context, 10);
    }

    @Override
    protected void onCreate() {
        super.onCreate();
        setSize(MenuUtils.getWindowWidth(context), MenuUtils.getScreenHeight(context));
        setTransparent(true);
        setBackColor(Color.TRANSPARENT);
        Component contentView = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_pop_menu, null, false);
        contentView.setBackground(createDrawable(ResourceTable.Color_tran));
        contentView.setLayoutConfig(new ComponentContainer.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_PARENT));
        setCustomComponent(contentView);
        content = (DirectionalLayout) contentView.findComponentById(ResourceTable.Id_content);
        DirectionalLayout out = (DirectionalLayout) contentView.findComponentById(ResourceTable.Id_out);
        itemWorb = (DirectionalLayout) contentView.findComponentById(ResourceTable.Id_item_worb);
        addItemChild();
        out.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                MenuPop.this.hide();
            }
        });
        content.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {

            }
        });
    }

    /**
     * getPopWidthType
     *
     * @return int
     */
    public int getPopWidthType() {
        return popWidthType;
    }

    /**
     * setPopWidthType
     *
     * @param popWidthType popWidthType
     */
    public void setPopWidthType(int popWidthType) {
        this.popWidthType = popWidthType;
    }

    private void addItemChild() {
        itemWorb.removeAllComponents();
        for (int i = 0; i < menuItems.size(); i++) {
            MenuItem menuItem = menuItems.get(i);
            Text text = new Text(context);

            text.setPaddingLeft(50);
            text.setPaddingRight(50);
            text.setTextSize(16, Text.TextSizeType.FP);
            text.setTextAlignment(TextAlignment.VERTICAL_CENTER);
            text.setText(menuItem.getTitle());
            int color = 0;

            try {
                if (menuItem.isEnabled()) {
                    color = context.getResourceManager().getElement(ResourceTable.Color_black).getColor();
                } else {
                    color = context.getResourceManager().getElement(ResourceTable.Color_uncheck_textcolor).getColor();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (NotExistException e) {
                e.printStackTrace();
            } catch (WrongTypeException e) {
                e.printStackTrace();
            }
            text.setTextColor(new Color(color));
            text.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    if (!menuItem.isEnabled()) {
                        return;
                    }
                    OnMenuItemClickListener onMenuItemClickListener = menuItem.getOnMenuItemClickListener();
                    if (onMenuItemClickListener != null) {
                        onMenuItemClickListener.onMenuItemClick(menuItem);
                    }
                    MenuPop.this.hide();
                }
            });
            ComponentContainer.LayoutConfig layoutConfig = text.getLayoutConfig();
            if (showBootom) {
                layoutConfig.width = ComponentContainer.LayoutConfig.MATCH_CONTENT;
            } else {
                layoutConfig.width = popWidthType == 0 ? ComponentContainer.LayoutConfig.MATCH_PARENT : (MenuUtils.getWindowWidth(context) - AttrHelper.vp2px(60, context));
            }

            layoutConfig.height = 150;
            text.setLayoutConfig(layoutConfig);
            if (menuItem.getType() == MeunItemType.HAS_SUB) {
                Resource resource = null;
                try {
                    resource = context.getResourceManager().getResource(ResourceTable.Media_right_arrow);
                    PixelMapElement element = new PixelMapElement(resource);
                    Rect rect = new Rect();
                    rect.left = 0;
                    rect.right = AttrHelper.vp2px(15, context);
                    rect.top = 0;
                    rect.bottom = AttrHelper.vp2px(15, context);
                    element.setBounds(rect);
                    text.setAroundElements(null, null, element, null);
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (NotExistException e) {
                    e.printStackTrace();
                }

            }
            itemWorb.addComponent(text);

        }
    }


    /**
     * doAttach
     *
     * @param component component
     */
    public void doAttach(Component component) {
        maxY = MenuUtils.getScreenHeight(context) - overflow;
        if (showBootom) {
            translationX = MenuUtils.getWindowWidth(context) - content.getWidth();
            translationY = MenuUtils.getScreenHeight(context) - content.getHeight() - MenuUtils.vp2px(context, 20);

        } else {
            final boolean isRTL = MenuUtils.isLayoutRtl(context);
            // 1. 获取atView在屏幕上的位置
            int[] locations = new int[2];
            int[] rectOld = component.getLocationOnScreen();
            locations[0] = rectOld[0];
            locations[1] = rectOld[1];
            final Rect rect = new Rect(locations[0], locations[1], locations[0] + component.getWidth(),
                    locations[1] + component.getHeight());
            final int centerX = (rect.left + rect.right) / 2;
            // 尽量优先放在下方，当不够的时候在显示在上方
            centerY = (float) (((double) rect.top + (double) rect.bottom) / 2);
            isShowUp = false;
            if (rect.bottom + content.getHeight() > (double) maxY + (double) getStatusBarHeight()) {
                if (centerY > (double) MenuUtils.getScreenHeight(context) / 2) { // 如果触摸点在屏幕中心的下方
                    isShowUp = true;
                }
            }
            isShowLeft = centerX < MenuUtils.getWindowWidth(context) / 2;
            // 修正高度，弹窗的高有可能超出window区域
            ComponentContainer.LayoutConfig params = content.getLayoutConfig();
            int maxHeight = isShowUp ? (int) (rect.top - (double) getStatusBarHeight() - overflow)
                    : (MenuUtils.getScreenHeight(context) - rect.top - overflow);

            int maxWidth = isShowLeft ? (MenuUtils.getWindowWidth(context) - rect.left - overflow) : (rect.right - overflow);
            if (content.getHeight() > maxHeight) {
                params.height = maxHeight;
            }

            if (content.getWidth() > maxWidth) {
                params.width = maxWidth;
            }
            content.setLayoutConfig(params);
            if (popWidthType == 0) {
                if (isRTL) {
                    translationX = isShowLeft ? -(MenuUtils.getWindowWidth(context) - rect.left - content.getWidth())
                            : -(MenuUtils.getWindowWidth(context) - rect.right);
                } else {
                    translationX = isShowLeft ? rect.left : (rect.right - content.getWidth());
                }
            } else {
                translationX = rect.left;
            }
            if (isShowUp) {
                // 说明上面的空间比较大，应显示在atView上方
                // translationX: 在左边就和atView左边对齐，在右边就和其右边对齐
                Logger.getLogger("TAG").log(Level.INFO, "rect.top:" + rect.top);
                Logger.getLogger("TAG").log(Level.INFO, "content.getHeight():" + content.getHeight());
                if ((rect.top - (double) getStatusBarHeight()) < content.getHeight()) {
                    translationY = AttrHelper.vp2px(10, context);
                } else {
                    translationY = (float) (rect.top - content.getHeight() - (double) getStatusBarHeight());
                }

            } else {
                translationY = (float) (rect.top - (double) getStatusBarHeight());

            }

        }
        content.setTranslationX(translationX);
        content.setTranslationY(translationY);

    }

    /**
     * getStatusBarHeight
     *
     * @return float
     */
    private float getStatusBarHeight() {

        return WindowUtil.getStatusBarHeightInPixels(context);
    }

    /**
     * createDrawable
     *
     * @param colorId colorId
     * @return ShapeElement
     */
    public ShapeElement createDrawable(int colorId) {
        ShapeElement drawable = new ShapeElement();
        int color = 0;
        try {
            color = context.getResourceManager().getElement(colorId).getColor();
            drawable.setRgbColor(RgbColor.fromArgbInt(color));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotExistException e) {
            e.printStackTrace();
        } catch (WrongTypeException e) {
            e.printStackTrace();
        }

        return drawable;
    }

    /**
     * setMenuItem
     *
     * @param menuItems menuItems
     */
    public void setMenuItem(ArrayList<MenuItem> menuItems) {
        this.menuItems = menuItems;


    }

    /**
     * setShowBootom
     *
     * @param showBootom showBootom
     */
    public void setShowBootom(boolean showBootom) {

        this.showBootom = showBootom;
    }

    /**
     * getShowBootom
     *
     * @return boolean
     */
    public boolean getShowBootom() {
        return showBootom;
    }
}
